﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
using System.Xml;
using System.Threading;
using System.IO;
using System.Data.OleDb;
using System.Runtime.InteropServices;
using System.Collections;

namespace SmsServer
{
    public partial class SmsServer : ServiceBase
    {
        public SmsServer()
        {
            InitializeComponent();
        }
        //导入sms.dll API
        [STAThread]

        [DllImport("sms.dll", EntryPoint = "Sms_Connection")]
        public static extern uint Sms_Connection(string CopyRight, uint Com_Port, uint Com_BaudRate, out string Mobile_Type, out string CopyRightToCOM);
        [DllImport("sms.dll", EntryPoint = "Sms_Disconnection")]
        public static extern uint Sms_Disconnection();
        [DllImport("sms.dll", EntryPoint = "Sms_Send")]
        public static extern uint Sms_Send(string Sms_TelNum, string Sms_Text);
        [DllImport("sms.dll", EntryPoint = "Sms_Receive")]
        public static extern uint Sms_Receive(string Sms_Type, out string Sms_Text);
        [DllImport("sms.dll", EntryPoint = "Sms_Delete")]
        public static extern uint Sms_Delete(string Sms_Index);
        [DllImport("sms.dll", EntryPoint = "Sms_AutoFlag")]
        public static extern uint Sms_AutoFlag();
        [DllImport("sms.dll", EntryPoint = "Sms_NewFlag")]
        public static extern uint Sms_NewFlag();
        //初始化变量
        int StrLen = 0;
        int ComPortNum = 0;
        Random random = new Random();
        ArrayList ComPort = readXML();

        protected override void OnStart(string[] args)
        {
            this.timSms.Enabled = true;
            writelog("SmsService 成功启动！");
        }

        protected override void OnStop()
        {
            this.timSms.Enabled = false;
            writelog("SmsService 成功停止！");
        }
        private void tSendSms()
        {
            try
            {
                Thread t1 = new Thread(new ThreadStart(sendSMS1));
                t1.Start();
            }
            catch
            {
                writelog("线程异常！");
            }
        }
        private void timSms_Elapsed_1(object sender, System.Timers.ElapsedEventArgs e)
        {
            //定时器
            this.tSendSms();
        }
        private void sendSMS1()
        {
            try
            {
                Sms_Disconnection();
            }
            catch
            {
                writelog("断开异常！");
            }
            try
            {
                StrLen = ComPort.Count;
                ComPortNum = random.Next(0, StrLen);
            }
            catch
            {
                writelog("随机端口生成异常！");
            }
            try
            {

                readAllData("OutBox", "data.mdb", (string)ComPort[ComPortNum]);
            }
            catch
            {
                writelog("发送总过程异常！");
            }
        }
        private bool SmsConnection(string MobPort)
        {
            String TypeStr = "";
            String CopyRightToCOM = "";
            String CopyRightStr = "//深圳市国爵电子有限公司,网址www.gprscat.com //";
            if (Sms_Connection(CopyRightStr, uint.Parse(MobPort), 9600, out TypeStr, out CopyRightToCOM) == 1) ///5为串口号，0为红外接口，1,2,3,...为串口
                return true;
            else
                return false;
        }
        private void readAllData(string tableName, string mdbPath, string ComPort)
        {
            List<NumMsg> nummsglist = new List<NumMsg>();
            List<NumMsg> numMsgFailList = new List<NumMsg>();
            try
            {
                string strConn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Windows.Forms.Application.StartupPath + "\\" + mdbPath + ";";
                OleDbConnection odcConnection = new OleDbConnection(strConn);
                odcConnection.Open();
                OleDbCommand odCommand = odcConnection.CreateCommand();
                odCommand.CommandText = "select top 100 ID,Mbno,Msg,failcount from " + tableName;
                OleDbDataReader odrReader = odCommand.ExecuteReader();
                while (odrReader.Read())
                {
                    NumMsg nummsg = new NumMsg();
                    if (odrReader[1].ToString() != "" && odrReader[2].ToString() != "")
                    {
                        nummsg.id = odrReader[0].ToString();
                        nummsg.num = odrReader[1].ToString();
                        nummsg.msg = odrReader[2].ToString();
                        nummsg.failCount = Convert.ToInt32(odrReader[3]);
                        if (nummsg.failCount > 3)
                        {
                            string strSql = "insert into badoutbox (mbno,msg,comport) values ('" + nummsg.num + "','" + nummsg.msg + "'," + ComPort + ")";
                            if (!ExecuteSql(strSql))
                                writelog("添加发送失败记录失败！");
                            strSql = "delete from OutBox where id=" + nummsg.id;
                            if (!ExecuteSql(strSql))
                                writelog("从OutBox删除发送失败记录错误!");

                        }
                        nummsglist.Add(nummsg);
                    }
                }
                //关闭连接
                odrReader.Close();
                odcConnection.Close();
                sendAllData(nummsglist, tableName, mdbPath, ComPort);
            }
            catch
            {
                writelog("读取所有数据失败位置:readAllData()！");
            }

        }
        private void sendAllData(List<NumMsg> nummsglist, string tableName, string mdbPath, string ComPort)
        {
            try
            {
                SmsConnection(ComPort);

            }
            catch
            {
                Sms_Disconnection();
                writelog("连接端口失败:" + ComPort);
            }
            foreach (NumMsg nummsg in nummsglist)
            {
                //writelog(nummsg.num + ":" + nummsg.msg + ":" + nummsg.failCount);
                if (Sms_Send(nummsg.num.ToString(), nummsg.msg.ToString()) == 1)
                {
                    string strsql = "insert into sendedOutBox" + " (mbno,msg,comport) values ('" + nummsg.num + "','" + nummsg.msg + "'," + ComPort + ")";
                    if (!ExecuteSql(strsql))
                        writelog("插入发送成功记录失败！");
                    strsql = "delete from OutBox where id=" + nummsg.id;
                    if (!ExecuteSql(strsql))
                        writelog("删除成功记录失败！");
                }
                else
                {
                    string strSql = "update " + tableName + " set failCount=" + (nummsg.failCount + 1).ToString() + " where id=" + nummsg.id;
                    if (!ExecuteSql(strSql))
                        writelog("更新发送错误次数失败！");
                }
            }
        }
        private bool ExecuteSql(string strSql)
        {
            try
            {
                string strConn = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + System.Windows.Forms.Application.StartupPath + "\\data.mdb;";
                OleDbConnection odcConnection = new OleDbConnection(strConn);
                odcConnection.Open();
                OleDbCommand odCommand = odcConnection.CreateCommand();
                odCommand.CommandText = strSql;
                //writelog(odCommand.CommandText);
                odCommand.ExecuteNonQuery();
                odcConnection.Close();
                return true;
            }
            catch
            {
                return false;
            }
        }
        private void writelog(string readme)
        {
            try
            {
                string Currpath = AppDomain.CurrentDomain.BaseDirectory;
                StreamWriter log = new StreamWriter(Currpath + "SmsServer.log", true);
                log.WriteLine(DateTime.Now.ToString("yyy-MM-dd HH:mm:ss") + ":" + readme);
                log.Close();
            }
            catch (Exception e)
            {
                EventLog log = new EventLog();
                log.Source = e.Source;
                log.WriteEntry(e.Message);
            }

        }
        public class NumMsg
        {
            public string id { get; set; }
            public string num { get; set; }
            public string msg { get; set; }
            public int failCount { get; set; }
        }
        public static ArrayList readXML()
        {
            ArrayList retIArr = new ArrayList();
            XmlDocument doc = new XmlDocument();
            string configFile = System.Windows.Forms.Application.StartupPath.ToString() + "\\Config.xml";
            doc.Load(configFile);
            XmlElement root = doc.DocumentElement;
            foreach (XmlNode node in root)
            {
                if (node.InnerText != "false")
                {
                    retIArr.Add(node.InnerText);
                }
            }
            return retIArr;
        }
    }
}
